#include "BaseGame.h"
#include "BasePlayer.h"
#include <algorithm>

BaseGame::BaseGame(unsigned int numHands, unsigned int handSize, unsigned int playerHandSize)
  : mGameStarted(false),
    mGameState(0, numHands, handSize),
    mPlayerHandSize(playerHandSize),
    mCurrentPlayer(0),
    mTurnID(rand())
{
}

bool BaseGame::attachPlayer(BasePlayer *player)
{
  bool ret(false);
  if (!mGameStarted)
  {
    mPlayers.push_back(player);
    mPlayerHands.push_back(CardList());
    mGameState.mHands.push_back(std::vector<CardList>(mGameState.mNumHands));
    ret = true;
  }
  return ret;
}

void BaseGame::nextTurn()
{
  if (mGameStarted)
  {
    mPlayers[mCurrentPlayer]->notifyTurn(mTurnID);
    //really need to work out how to do this
    //right now nextTurn calls player->notifyTurn
    //which should wait for a game->playCard function
    //to be called. In short, I should rethink this
    //and redraw the whole system. Using callbacks
    //requires threads and a control loop. Is this
    //something I want? Or should I restructure it?
  }
}

bool BaseGame::startGame()
{
  bool ret(false);
  if (!mGameStarted)
  {
    shuffle();
    deal();
    ret = mGameStarted = true;
  }
  return ret;
}

void BaseGame::shuffle()
{
  std::vector<Card> deck;
  for(unsigned int rank(0); rank < mGameState.mNumHands+1; ++rank) //numHands+1 = minimum number of ranks plus one for more interesting games
  {
    for(unsigned int suit(0); suit < mGameState.numPlayers()*mGameState.mHandSize; ++suit)
    {
      deck.push_back(Card(suit, rank));
    }
  }
  std::random_shuffle(deck.begin(), deck.end());
  mDeck = CardList(deck.begin(), deck.end());
}

void BaseGame::deal()
{
  for (unsigned int player(0); player < mGameState.numPlayers(); ++player)
  {
    for(unsigned int card(0); card < mPlayerHandSize && mDeck.size(); ++card)
    {
      mPlayerHands[player].push_back(mDeck.front());
      mDeck.pop_front();
    }
    mPlayers[player]->setHand(mPlayerHands[player]);
  }
}
